<?php

/**
 * Created by PhpStorm.
 * Author: ls
 * Time: 2023/9/22 10:43
 * Desc: 优惠券
 */
class Service_Api_Coupon extends Contract_Api_Coupon
{
    public function receive_list(array $params): array
    {
        /**
         * @var $type_id
         * @var $special_id
         */
        extract($params);

        $page     = Arr::get($params, 'page', 1);
        $pagesize = Arr::get($params, 'pagesize', 10);
        $mid      = Arr::get($params, 'mid', '');
        $kindid   = Arr::get($params, 'kindid', '');

        $time    = time();
        $builder = DB::select('id', 'kindid', 'name', 'type', 'isnever', 'starttime', 'endtime', 'samount', 'antedate',
            'totalnumber', 'maxnumber', 'typeid', 'amount', 'code', 'memeber_grades', 'modules', 'needjifen')
            ->from('coupon')
            ->where('isopen', '=', 1)
            ->and_where('isdel', '=', 0)
            ->and_where_open()
            ->where('endtime', '>', $time)
            ->or_where('isnever', '=', 0)
            ->and_where_close();

        if (St_Functions::is_normal_app_install('system_wallet')) {
            $builder->and_where('usage_scenario', '=', 0);
        }
        if($kindid){
            $builder->and_where('kindid', '=', $kindid);
        }
        if (!empty($type_id)) {
            $builder->and_where_open()
                ->where('typeid', '=', 0)
                ->where(DB::expr(" OR (find_in_set($type_id,modules) and typeid=1) "));

            $coupon_pro = DB::select()
                ->from('coupon_pro')
                ->where('typeid', '=', $type_id)
                ->execute()
                ->as_array('id', 'cid');
            if (!empty($coupon_pro)) {
                $pro_ids = array_unique(array_values($coupon_pro));
                $builder->where(DB::expr(" OR (typeid=9999 and id in (" . implode(',', $pro_ids) . ")) "));
            }

            $builder->and_where_close();
        }

        if (!empty($special_id)) {
            $zt_channel_coupon = DB::select()
                ->from('zt_channel_coupon')
                ->where('channelid', '=', $special_id)
                ->execute()
                ->as_array('id', 'couponid');
            if (!empty($zt_channel_coupon)) {
                $special_ids = array_unique(array_values($zt_channel_coupon));
                $builder->and_where('id', 'in', $special_ids);
                $builder->and_where('kindid', '=', 1);
            }
        }

        $offset = St_Page::offset($page, $pagesize);
        $list   = $builder->order_by(DB::expr("IFNULL(displayorder,9999)"), 'asc')
            ->offset($offset)
            ->limit($pagesize)
            ->execute()
            ->as_array();

        $data = array();
        if (!empty($list)) {
            $all_grade = Model_Api_V2_Coupon::get_all_member_grade();
            foreach ($list as &$item) {
                // 可使用产品类型
                $item['typename'] = $item['typeid'] != 0 ? Model_Api_V2_Coupon::get_coupon_type($item['id'], $item) : '';

                // 是否可以领取
                $check_receive_status = Model_Api_V2_Coupon::check_receive_status($item['id'], $mid, $item['totalnumber'], $item['maxnumber']);
                $item['status']       = $check_receive_status['status'];
                $item['surplus']      = abs($check_receive_status['surplus']);

                // 会员等级限制
                $grade_name            = Model_Api_V2_Coupon::get_member_grade($item['memeber_grades'], $all_grade);
                $item['gradename_all'] = $grade_name['gradename_all'];
                $item['gradename']     = $grade_name['gradename'];

                // 格式化优惠券返回数据
                $item = Model_Api_V2_Coupon::format_return_data($item);

                unset($item['memeber_grades']);
                unset($item['typeid']);
            }

            $data = Model_Coupon::get_data($list);
        }

        return $data;
    }

    public function receive(int $mid, int $id): array
    {
        //根据优惠券扣积分
        $coupon = DB::select()
            ->from('coupon')
            ->where('id', '=', $id)
            ->execute()
            ->current();
        if (!$coupon) {
            throw new Exception('优惠券不存在');
        }

        $receive_code   = 1;
        $receive_status = Model_Api_V2_Coupon::check_receive_status($id, $mid, $coupon['totalnumber'], $coupon['maxnumber']);
        if ($receive_status['status'] != 1) {
            $receive_code = $receive_status['status'];
        } else {
            //判断发卷方式 1 免费  2 积分
            if ($coupon['kindid'] == 2) {
                //需要积分
                $needjifen = $coupon['needjifen'];
                //判断用户积分是否满足领取积分的条件
                $member = ORM::factory('member')
                    ->where('mid', '=', $mid)
                    ->find();
                if ($member->jifen < $needjifen) {
                    $receive_code = 5; // 积分不足
                } else {
                    //领取优惠券
                    list($member_coupon_id) = Model_Coupon::get_coupon($id, $mid,$coupon['kindid']);
                    if (!$member_coupon_id) {
                        throw new Exception('领取失败, 请重试');
                    }
                    $new_jifen = $member->jifen - $needjifen;
                    //扣除积分并写记录
                    $member->jifen = $new_jifen;
                    $member->save();
                    if (!$member->saved()) {
                        throw new Exception('领取失败');
                    }
                    //写积分日志
                    $log = '积分领取优惠券:' . $coupon['name'] . ',使用' . $needjifen . '积分';
                    Model_Member_Jifen_Log::add_jifen_log($mid, $log, $needjifen, 1);
                }
            }
        }

        // 执行优惠券 免费领取
        if ($receive_code == 1 && $coupon['kindid'] != 2 ) {
            list($member_coupon_id) = Model_Coupon::get_coupon($id, $mid);
            if (!$member_coupon_id) {
                throw new Exception('领取失败, 请重试');
            }
        }

        $result = array(
            'status' => false
        );
        switch ($receive_code) {
            case 1:
                $result['status'] = true;
                $msg              = '领取成功';
                break;
            case 2:
                $msg = '已领完';
                break;
            case 3:
                $msg = '已经领取，待使用';
                break;
            case 4:
                $msg = '会员等级不满足';
                break;
            case 5:
                $msg = '积分不足';
                break;
        }

        $result['msg'] = $msg;
        return $result;
    }

    public function member_coupon(int $mid, array $params): array
    {
        $page     = Arr::get($params, 'page', 1);
        $pagesize = Arr::get($params, 'pagesize', 10);
        $type     = Arr::get($params, 'type', 0); //0全部 1:未使用；2：已失效 3：已使用

        $time   = time();
        $offset = St_Page::offset($page, $pagesize);

        $coupon_fields        = array(
            'sline_coupon.id', 'sline_coupon.name', 'sline_coupon.type', 'sline_coupon.isnever',
            'sline_coupon.starttime', 'sline_coupon.endtime', 'sline_coupon.samount',
            'sline_coupon.totalnumber', 'sline_coupon.maxnumber', 'sline_coupon.typeid', 'sline_coupon.amount',
            'sline_coupon.code', 'sline_coupon.memeber_grades', 'sline_coupon.modules'
        );
        $member_coupon_fields = array(
            'sline_member_coupon.cid', 'sline_member_coupon.totalnum', 'sline_member_coupon.usenum'
        );
        $fields               = array_merge($coupon_fields, $member_coupon_fields);
        $fields_str           = implode(',', $fields);

        $builder = DB::select(DB::expr($fields_str))
            ->from('member_coupon')
            ->join('coupon', 'LEFT')
            ->on('coupon.id', '=', DB::expr('sline_member_coupon.cid'))
            ->where('member_coupon.mid', '=', $mid)
            ->and_where('coupon.isdel', '=', 0);
        switch ($type) {
            case 1://未使用
                $builder->and_where('member_coupon.usenum', '<', DB::expr('sline_member_coupon.totalnum'));
                $builder->and_where_open()
                    ->where('coupon.endtime', '>', $time)
                    ->or_where('coupon.isnever', '=', 0)
                    ->and_where_close();
                break;
            case 2: //已失效
                $builder->and_where('coupon.endtime', '<', $time)
                    ->and_where('coupon.isnever', '=', 1);
                break;
            case 3://已使用
                $builder->and_where('member_coupon.usenum', '=', DB::expr('sline_member_coupon.totalnum'));
                break;
        }

        $list = $builder->order_by('member_coupon.usetime', 'asc')
            ->order_by('coupon.isnever', 'asc')
            ->order_by('coupon.endtime', 'desc')
            ->offset($offset)
            ->limit($pagesize)
            ->execute()
            ->as_array();

        foreach ($list as &$item) {
            // 可使用产品类型
            $item['typename'] = $item['typeid'] != 0 ? Model_Api_V2_Coupon::get_coupon_type($item['id'], $item) : '';

            // 优惠券使用状态
            $item['use_status'] = Model_Api_V2_Coupon::get_use_status($item);

            // 格式化优惠券返回数据
            $item = Model_Api_V2_Coupon::format_return_data($item);

            unset($item['memeber_grades']);
            unset($item['typeid']);
            unset($item['modules']);
            unset($item['needjifen']);
            unset($item['cid']);
        }

        return $list;
    }

    public function member_coupon_jifen(int $mid, array $params): array
    {
        $page     = Arr::get($params, 'page', 1);
        $pagesize = Arr::get($params, 'pagesize', 10);
        $type     = Arr::get($params, 'type', 0); //0全部 1:未使用；2：已失效 3：已使用

        $time   = time();
        $offset = St_Page::offset($page, $pagesize);

        $coupon_fields        = array(
            'sline_coupon.id', 'sline_coupon.name', 'sline_coupon.type', 'sline_coupon.isnever',
            'sline_coupon.starttime', 'sline_coupon.endtime', 'sline_coupon.samount',
            'sline_coupon.totalnumber', 'sline_coupon.maxnumber', 'sline_coupon.typeid', 'sline_coupon.amount',
            'sline_coupon.code', 'sline_coupon.memeber_grades', 'sline_coupon.modules'
        );
        $member_coupon_fields = array(
            'sline_member_coupon.cid', 'sline_member_coupon.totalnum', 'sline_member_coupon.usenum'
        );
        $fields               = array_merge($coupon_fields, $member_coupon_fields);
        $fields_str           = implode(',', $fields);

        $builder = DB::select(DB::expr($fields_str))
            ->from('member_coupon')
            ->join('coupon', 'LEFT')
            ->on('coupon.id', '=', DB::expr('sline_member_coupon.cid'))
            ->where('member_coupon.mid', '=', $mid)
            ->and_where('coupon.isdel', '=', 0)
            ->and_where('member_coupon.claim_type', '=', 1);
        switch ($type) {
            case 1://未使用
                $builder->and_where('member_coupon.usenum', '<', DB::expr('sline_member_coupon.totalnum'));
                $builder->and_where_open()
                    ->where('coupon.endtime', '>', $time)
                    ->or_where('coupon.isnever', '=', 0)
                    ->and_where_close();
                break;
            case 2: //已失效
                $builder->and_where('coupon.endtime', '<', $time)
                    ->and_where('coupon.isnever', '=', 1);
                break;
            case 3://已使用
                $builder->and_where('member_coupon.usenum', '=', DB::expr('sline_member_coupon.totalnum'));
                break;
        }

        $list = $builder->order_by('member_coupon.usetime', 'asc')
            ->order_by('coupon.isnever', 'asc')
            ->order_by('coupon.endtime', 'desc')
            ->offset($offset)
            ->limit($pagesize)
            ->execute()
            ->as_array();

        foreach ($list as &$item) {
            // 可使用产品类型
            $item['typename'] = $item['typeid'] != 0 ? Model_Api_V2_Coupon::get_coupon_type($item['id'], $item) : '';

            // 优惠券使用状态
            $item['use_status'] = Model_Api_V2_Coupon::get_use_status($item);

            // 格式化优惠券返回数据
            $item = Model_Api_V2_Coupon::format_return_data($item);

            unset($item['memeber_grades']);
            unset($item['typeid']);
            unset($item['modules']);
            unset($item['needjifen']);
            unset($item['cid']);
        }

        return $list;
    }


    public function check_samount(int $mid, array $params): array
    {
        /**
         * @var $role_id
         * @var $total_price
         * @var $type_id
         * @var $product_id
         * @var $start_time
         */
        extract($params);
        return Model_Coupon::check_samount($role_id, $total_price, $type_id, $product_id, $start_time, $mid);
    }

    public function product_use_list(int $mid, array $params): array
    {
        /**
         * @var $model_type_id
         * @var $product_id
         */
        extract($params);

        return Model_Api_V2_Coupon::get_product_coupon($model_type_id, $product_id, $mid);
    }

    public function use_product(array $params): array
    {
        /**
         * @var $cid
         * @var $type_id
         * @var $page
         * @var $pagesize
         */
        extract($params);

        $coupon = DB::select('typeid', 'modules', 'name')
            ->from('coupon')
            ->where('id', '=', $cid)
            ->and_where('isopen', '=', 1)
            ->and_where('isdel', '=', 0)
            ->execute()
            ->current();

        if (!$coupon) {
            throw new Exception('优惠券不存在');
        }

        $type_ids    = array();
        $product_ids = array();
        if ($coupon['typeid'] == 1) {
            $type_ids = explode(',', $coupon['modules']);
        } else {
            if ($coupon['typeid'] == 0) {
                $type_ids = Model_Api_V2_Coupon::get_allow_product_model();
            } else {
                $product_list = DB::select('proid', 'typeid')
                    ->from('coupon_pro')
                    ->where('cid', '=', $cid)
                    ->execute()
                    ->as_array();
                foreach ($product_list as $product) {
                    if (!in_array($product['typeid'], $type_ids)) {
                        $type_ids[] = $product['typeid'];
                    }
                    if (!isset($product_ids[$product['typeid']])) {
                        $product_ids[$product['typeid']] = [];
                    }
                    $product_ids[$product['typeid']][] = $product['proid'];
                }
            }
        }

        // 指定产品类型时需要判断是否在当前优惠券类型里面
        if (!empty($type_id)) {
            if (!in_array($type_id, $type_ids)) {
                throw new Exception('不支持该产品类型');
            }
        }

        // 获取使用产品的分类
        $navs = Model_Api_V2_Coupon::get_use_product_nav($type_ids);

        //去除没有产品的优惠券分类
        foreach ($navs as $key => $vel) {
            if ($vel['num'] == 0) {
                unset($navs[$key]);
            }
        }

        // 获取产品
        $products = array();
        if (!empty($navs)) {
            $navs = array_values($navs);
            // 未指定产品类型时展示第一个产品类型的产品
            if (empty($params['type_id'])) {
                $params['type_id'] = $navs[0]['typeid'];
            }
            // 指定产品id
            if (isset($product_ids[$params['type_id']])) {
                $params['product_ids'] = $product_ids[$params['type_id']];
            }
            $products = Model_Api_V2_Coupon::get_use_product($params);

            if ($params['type_id'] > 200) {
                $table = 'model';
            } else {
                $module = ORM::factory('model', $params['type_id']);
                $table  = $module->maintable;
            }

            foreach ($products as &$v) {
                $product      = ORM::factory($table, $v['tid'])->as_array();
                $v['price']   = $product['price'];//价格
                $v['sellnum'] = $product['bookcount'];// 销量
                // 产品信息
                if(!in_array($params['type_id'],[111])){
                    $v['attrlist'] = Model_Api_V2_Coupon::get_product_attr($product['attrid'], $table);
                }
                $v['litpic']   = $this->img_url($product['litpic']);
                $v['score']    = St_Functions::get_satisfy($v['typeid'], $product['id'], $product['satisfyscore']);
            }
        }

        return array(
            'navs' => $navs,
            'list' => $products
        );
    }

    public function get_coupon_list(array $params, $mid = 0): array
    {
        /**
         * @var $type_id
         * @var $product_id
         */
        extract($params);

        $coupon_list = Model_Coupon::get_product_coupon_list($product_id, $type_id);
        if ($mid) {
            // 处理个人优惠券
            foreach ($coupon_list as $key => $v) {
                $receive_status = Model_Api_V2_Coupon::check_receive_status($v['id'], $mid, $v['totalnumber'], $v['maxnumber']);
                if ($v['typeid'] == 0) {
                    $coupon_list[$key]['typename'] = '无品类限制';
                } else {
                    $coupon_list[$key]['typename'] = Model_Api_V2_Coupon::get_coupon_type($v['id'], $v);
                }
                $coupon_list[$key]['surplus'] = abs($receive_status['surplus']);
                //去掉过期优惠券
                if ($v['isnever'] != 0 && $v['endtime'] != 0 && $v['endtime'] <= time()) {
                    unset($coupon_list[$key]);
                }
            }
            //重新循环遍历输出,便于JS端操作处理.
            $coupon_list = array_values($coupon_list);
        }
        return array("list" => $coupon_list);
    }

    public function get_coupon_category(array $params): array
    {
        /**
         * @var $siteId
         * @var $secret
         * @var string $typeidstr // 前端展示的产品
         * @var $mini_type
         */
        extract($params);
        // 获取权限
        $result = Model_Api_V2_System::get_xcx_auth($mini_type, $siteId, $secret);
        // 获取产品限制
        $product_type_id = Model_Api_V2_System::get_xcx_product_typeid($result);
        // 获取所有模块
        $models = DB::select()
            ->from('model')
            ->where('id', 'in', $product_type_id)
            ->execute()
            ->as_array();
        //筛选限制typeid
        $type_id_arr = explode(",", $typeidstr);

        $data = array();

        $time = time();
        foreach ($models as $item) {
            $type_id = $item['id'];

            $builder = DB::select()
                ->from('coupon')
                ->where('isopen', '=', 1)
                ->and_where('isdel', '=', 0)
                ->and_where('kindid', '=', 1)
                ->and_where_open()
                ->where('endtime', '>', $time)
                ->or_where('isnever', '=', 0)
                ->and_where_close();

            $builder->and_where_open()
                ->where('typeid', '=', 0)
                ->where(DB::expr(" OR (find_in_set($type_id,modules) and typeid=1) "));
            $coupon_pro = DB::select()
                ->from('coupon_pro')
                ->where('typeid', '=', $type_id)
                ->execute()
                ->as_array('id', 'cid');
            if (!empty($coupon_pro)) {
                $pro_ids = array_unique(array_values($coupon_pro));
                $builder->where(DB::expr(" OR (typeid=9999 and id in (" . implode(',', $pro_ids) . ")) "));
            }
            $builder->and_where_close();

            $total = $builder->execute()->count();
            if ($total == 0) {
                continue;
            }

            if (!empty($type_id_arr) && !in_array($type_id, $type_id_arr)) {
                continue;
            }

            $data[] = array(
                'id' => $item['id'],
                'modulename' => $item['modulename'],
            );
        }
        return $data;
    }
}